<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Artisan;
use Inertia\Inertia;
use Inertia\Response;

class QueueController extends Controller
{
    /**
     * 显示队列状态
     */
    public function index(): Response
    {
        $stats = $this->getQueueStats();
        $recentJobs = $this->getRecentJobs();
        $failedJobs = $this->getFailedJobs();
        $queueHealth = $this->getQueueHealth();

        return Inertia::render('Admin/Queue/Index', [
            'stats' => $stats,
            'recentJobs' => $recentJobs,
            'failedJobs' => $failedJobs,
            'queueHealth' => $queueHealth,
        ]);
    }

    /**
     * 获取队列统计信息
     */
    private function getQueueStats(): array
    {
        $connection = config('queue.default');
        
        $stats = [
            'connection' => $connection,
            'pending_jobs' => 0,
            'failed_jobs' => 0,
            'processed_jobs' => 0,
            'queue_size' => 0,
        ];

        try {
            if ($connection === 'database') {
                $stats['pending_jobs'] = DB::table('jobs')->count();
                $stats['failed_jobs'] = DB::table('failed_jobs')->count();
                
                // 获取最近处理的作业数量（通过日志或其他方式）
                $stats['processed_jobs'] = $this->getProcessedJobsCount();
            } elseif ($connection === 'redis') {
                $redis = Redis::connection();
                $stats['pending_jobs'] = $redis->llen('queues:default');
                $stats['failed_jobs'] = $redis->llen('queues:default:failed');
                $stats['queue_size'] = $redis->llen('queues:default');
            }
        } catch (\Exception $e) {
            // 如果无法获取统计信息，记录错误但不中断
            \Log::error('Failed to get queue stats: ' . $e->getMessage());
        }

        return $stats;
    }

    /**
     * 获取最近的作业
     */
    private function getRecentJobs(): array
    {
        try {
            if (config('queue.default') === 'database') {
                return DB::table('jobs')
                    ->select('id', 'queue', 'payload', 'attempts', 'reserved_at', 'available_at', 'created_at')
                    ->orderBy('created_at', 'desc')
                    ->limit(10)
                    ->get()
                    ->map(function ($job) {
                        $payload = json_decode($job->payload, true);
                        return [
                            'id' => $job->id,
                            'queue' => $job->queue,
                            'job' => $payload['displayName'] ?? 'Unknown',
                            'attempts' => $job->attempts,
                            'reserved_at' => $job->reserved_at,
                            'available_at' => $job->available_at,
                            'created_at' => $job->created_at,
                        ];
                    })
                    ->toArray();
            }
        } catch (\Exception $e) {
            \Log::error('Failed to get recent jobs: ' . $e->getMessage());
        }

        return [];
    }

    /**
     * 获取失败的作业
     */
    private function getFailedJobs(): array
    {
        try {
            return DB::table('failed_jobs')
                ->select('id', 'uuid', 'connection', 'queue', 'payload', 'exception', 'failed_at')
                ->orderBy('failed_at', 'desc')
                ->limit(10)
                ->get()
                ->map(function ($job) {
                    $payload = json_decode($job->payload, true);
                    return [
                        'id' => $job->id,
                        'uuid' => $job->uuid,
                        'queue' => $job->queue,
                        'job' => $payload['displayName'] ?? 'Unknown',
                        'exception' => substr($job->exception, 0, 200) . '...',
                        'failed_at' => $job->failed_at,
                    ];
                })
                ->toArray();
        } catch (\Exception $e) {
            \Log::error('Failed to get failed jobs: ' . $e->getMessage());
            return [];
        }
    }

    /**
     * 获取队列健康状态
     */
    private function getQueueHealth(): array
    {
        $health = [
            'status' => 'healthy',
            'issues' => [],
            'recommendations' => [],
        ];

        try {
            $stats = $this->getQueueStats();
            
            // 检查队列大小
            if ($stats['pending_jobs'] > 100) {
                $health['status'] = 'warning';
                $health['issues'][] = '队列中有大量待处理任务';
                $health['recommendations'][] = '考虑增加队列工作进程数量';
            }

            // 检查失败任务
            if ($stats['failed_jobs'] > 10) {
                $health['status'] = 'warning';
                $health['issues'][] = '有多个失败的任务';
                $health['recommendations'][] = '检查失败任务并重试';
            }

            // 检查队列连接
            if (config('queue.default') === 'sync') {
                $health['status'] = 'warning';
                $health['issues'][] = '队列使用同步模式，可能影响性能';
                $health['recommendations'][] = '考虑使用 Redis 或数据库队列';
            }

        } catch (\Exception $e) {
            $health['status'] = 'error';
            $health['issues'][] = '无法获取队列状态: ' . $e->getMessage();
        }

        return $health;
    }

    /**
     * 获取已处理作业数量（估算）
     */
    private function getProcessedJobsCount(): int
    {
        try {
            // 这里可以通过日志文件或其他方式获取
            // 暂时返回一个估算值
            return DB::table('jobs')->where('attempts', '>', 0)->count();
        } catch (\Exception $e) {
            return 0;
        }
    }

    /**
     * 重试失败的作业 - 使用 Inertia.js 重定向
     */
    public function retryFailedJobs(Request $request)
    {
        try {
            $jobId = $request->input('job_id');
            
            if ($jobId) {
                // 重试特定作业
                Artisan::call('queue:retry', ['id' => $jobId]);
                $message = "作业 #{$jobId} 已加入重试队列";
            } else {
                // 重试所有失败作业
                Artisan::call('queue:retry', ['id' => 'all']);
                $message = "所有失败作业已加入重试队列";
            }

            return redirect()->back()->with('success', $message);
        } catch (\Exception $e) {
            return redirect()->back()->with('error', '重试失败: ' . $e->getMessage());
        }
    }

    /**
     * 清空队列 - 使用 Inertia.js 重定向
     */
    public function clearQueue(Request $request)
    {
        try {
            $queue = $request->input('queue', 'default');
            
            Artisan::call('queue:clear', ['--queue' => $queue]);
            
            return redirect()->back()->with('success', "队列 '{$queue}' 已清空");
        } catch (\Exception $e) {
            return redirect()->back()->with('error', '清空队列失败: ' . $e->getMessage());
        }
    }

    /**
     * 删除失败的作业 - 使用 Inertia.js 重定向
     */
    public function deleteFailedJob(Request $request, $jobId)
    {
        try {
            if (!$jobId) {
                return redirect()->back()->with('error', '请提供作业ID');
            }

            DB::table('failed_jobs')->where('id', $jobId)->delete();
            
            return redirect()->back()->with('success', "失败作业 #{$jobId} 已删除");
        } catch (\Exception $e) {
            return redirect()->back()->with('error', '删除失败: ' . $e->getMessage());
        }
    }

}
